package cn.tedu.orderservice.job;

import cn.tedu.charging.common.pojo.dto.GunStatusParam;
import cn.tedu.charging.common.response.JsonResult;
import cn.tedu.orderservice.constant.Constant;
import cn.tedu.orderservice.feign.DeviceClient;
import cn.tedu.orderservice.feign.UserClient;
import cn.tedu.orderservice.pojo.dto.DeviceChargingDTO;
import cn.tedu.orderservice.pojo.po.ChargingBillFailPO;
import cn.tedu.orderservice.pojo.po.ChargingBillSuccessPO;
import cn.tedu.orderservice.repository.OrderRepository;
import cn.tedu.orderservice.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;

@Slf4j
public class DeviceCheckJob implements Job {
    /**
     * 必须无参的构造器
     * 如果没有,在初始化的时候 newInstance 通过getConstructor0 获取构造器来初始化
     * NoSuchMethodException 找不到方法 找不到默认构造器
     */
    public DeviceCheckJob(){}

    /**
     * 设置固定频率
     */
    public DeviceCheckJob(String orderNo, Long gunId) throws Exception {
        log.debug("添加设备自检定时任务:{}",orderNo);
        //创建调度器工厂
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        //通过调度器工厂获取调度器
        Scheduler scheduler = schedulerFactory.getScheduler();

        //创建定时任务
        JobDetail jobDetail = JobBuilder.newJob(DeviceCheckJob.class)
                //定义定时任务的名称和组
                .withIdentity("DeviceCheckJob" + UUID.randomUUID(), "device_check_job")
                //传入订单号
                .usingJobData("orderNo", orderNo)
                //传入枪id
                .usingJobData("gunId",gunId)
                //构建
                .build();

        //当前时间
        long now = System.currentTimeMillis();
        //设备自检需要两分钟
        long deviceCheckTime =  4*60 * 1000;
        //任务触发的时间
        Date triggerTime = new Date(now + deviceCheckTime);
        //创建触发器 并 设置时间
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .startAt(triggerTime)
                .build();

        //定时任务和触发器绑定到调度
        scheduler.scheduleJob(jobDetail,trigger);

        //启动调度器
        scheduler.start();

    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.debug("定时任务开始执行");
        //通过ApplicationContext获取bean,拿到数据库操作对象
        OrderRepository orderRepository =(OrderRepository) SpringContextUtil.getBean("orderRepositoryImpl");

//        UserClient userClient=(UserClient)SpringContextUtil.getBean("userservice");
//        JsonResult<BigDecimal> userBalance = userClient.getUserBalance(1l);
//        log.debug("--------------------金额:{}",userBalance);

        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        String orderNo = jobDataMap.getString("orderNo");
        Long gunId = jobDataMap.getLong("gunId");
        log.debug("从自检任务中提取订单号:{},枪id:{}",orderNo,gunId);
        //1.设备接收到充电指令,充电成功
        //2.设备收到指令,充电失败
        //3.没有返回消息

        //判断订单成功表中有没有数据
        ChargingBillSuccessPO chargingBillSuccessPO = orderRepository.getSuccess(orderNo);
        if (chargingBillSuccessPO == null) {
            //没有成功订单数据
            //判断订单失败表中有没有数据
            ChargingBillFailPO dbChargingBillFailPO = orderRepository.getFail(orderNo);
            if (dbChargingBillFailPO == null) {
                //没有失败订单数据
                DeviceChargingDTO deviceChargingDTO=new DeviceChargingDTO();
                deviceChargingDTO.setOrderNo(orderNo);
                deviceChargingDTO.setGunId(gunId);
                log.debug("Z-1没有成功订单,也没有失败订单,设备故障,新增失败数据:{}",deviceChargingDTO);
                orderRepository.saveFailed(deviceChargingDTO);
            }else {
                //这部分逻辑在mqtt返回失败结果时处理了
                //如果有失败订单有记录 设备失败是 "设备自检失败-设备有响应但是充不了电"
                //这的逻辑无需 把设备失败的原因 改为  "设备无响应"
            }
            //没有数据 设备故障了 更改设备状态
            GunStatusParam updateParam = new GunStatusParam();
            updateParam.setStatus(Constant.GUN_STATS_ERROR);
            updateParam.setGunId(gunId);
            log.debug("Z-2更改设备状态:{}",updateParam);
            //deviceClient.updateGunStatus(updateParam);
            //可以扩展业务,上报充电枪故障,通过rabbit-mq 通知 报障服务,服务人员接收到消息,进行设备检查
        }else {
            //有成功的订单数据 --完善订单数据的操作
            // 把用户id,枪id,运营商id,车辆id,充电站id 更新到订单表
            log.debug("Z-3更新订单信息 订单id:{},枪id:{},",orderNo,gunId);
            orderRepository.updateSuccessOrder(orderNo,gunId);
        }
    }
}
